package com.example.forum.controller;


import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;

import com.example.forum.commons.annotations.UncheckToken;
import com.example.forum.commons.authrization.TokenManager;
import com.example.forum.commons.jwt.JwtHelper;
import com.example.forum.commons.jwt.LoginUserModel;
import com.example.forum.commons.tools.JsonUtil;
import com.example.forum.commons.tools.StringUtil;
import com.example.forum.commons.tools.Transfer.DataTransfer;
import com.example.forum.commons.tools.Utils;
import com.example.forum.commons.tools.redis.RedisHelper;
import com.example.forum.entity.TUserroles;
import com.example.forum.entity.TUsers;
import com.example.forum.enums.LoginResults;
import com.example.forum.service.ITPermissionsService;
import com.example.forum.service.ITUserrolesService;
import com.example.forum.service.ITUsersService;
import com.example.forum.vo.JsonResult;
import com.example.forum.vo.UserModel;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import io.swagger.annotations.ApiParam;
import net.logstash.logback.encoder.org.apache.commons.lang.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.http.HttpStatus;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.RestController;

import javax.validation.Valid;
import java.util.ArrayList;
import java.util.List;
import java.util.Random;
import java.util.UUID;

/**
 * <p>
 * 前端控制器
 * </p>
 *
 * @author why
 * @since 2019-10-30
 */

@RestController
@Api(tags = "用户控制层")
@RequestMapping("/User")
public class TUsersController extends BaseController {

    private static final Logger LOGGER = LoggerFactory.getLogger(TUsersController.class);
    @Autowired
    private ITUsersService userService;
    @Autowired
    private ITUserrolesService userRoleService;
    @Autowired
    private ITPermissionsService permissionsService;
    @Autowired
    DataTransfer dataTransfer;
    @Autowired
    private TokenManager tokenManager;

    @Autowired
    private JwtHelper jwtHelper;
    @Autowired
    private RedisHelper redisHelper;

    private static String LoginErrorTimes_Prefix = "LoginErrorTimes.User.";

    @ApiOperation(value = "调取用户信息")
    @RequestMapping(value = "/showInfos", method = {RequestMethod.GET})
    public JsonResult showInfos() {
        LOGGER.info("查询用户全部用户");
        //List<com.java.core.dto.TestDto> userInfos = testService.findAll();
        QueryWrapper<TUsers> queryWrapper = new QueryWrapper<TUsers>();
        Page<TUsers> page = new Page();
        page.setSize(10);
        page.setCurrent(1);
        IPage<TUsers> page2 = userService.page(page, queryWrapper);
        return new JsonResult(HttpStatus.OK, "测试 ", page2.getRecords());
    }

    final String defaultValue = "00000000-0000-0000-0000-000000000000";

    @ApiOperation(value = "注册用户")
    @RequestMapping(value = "/register", method = {RequestMethod.POST})
    public JsonResult register(@Valid @RequestBody @ApiParam(name = "用户对象", value = "传入json格式", required = true) UserModel usermodel) {
        LOGGER.info("注册用户");
        var users = userService.list(new QueryWrapper<TUsers>().eq("username", usermodel.getUsername()));
        if (users != null && users.size() != 0) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该用户已存在 ", null);
        }
        TUsers usert = new TUsers();
        usert = (TUsers) dataTransfer.getObjectFromObject(usert, usermodel);
        usert.setIsemailconfirmed(false);
        usert.setIsphonenumconfirmed(false);
        usert.setIslocked(false);
        usert.setPoststationid(defaultValue);
        usert.setUsersource(0);
        if (usert.getStreetid() == null) {
            usert.setStreetid(defaultValue);
        }
        if (usert.getRegionid() == null) {
            usert.setRegionid(defaultValue);
        }
        if (usert.getNeighborhoodcommitteeid() == null) {
            usert.setNeighborhoodcommitteeid(defaultValue);
        }

        Integer saltrandom = new Random().nextInt(999999) + 100000;
        String salts = saltrandom.toString();
        usert.setPassword(Utils.md5Encoding(Utils.md5Encoding(usermodel.getPassword()) + salts));
        usert.setSalt(salts);
        var returnuserid = userService.save(usert);
        //分派
        if (usermodel.getRegistertype() == 1 && usermodel.getRoles() != null && usermodel.getRoles().length > 0) {
            var user = userService.getOne(new QueryWrapper<TUsers>().eq("username", usermodel.getUsername()));

            for (String role : usermodel.getRoles()) {
                TUserroles urdto = new TUserroles();
                urdto.setRoleid(role);
                urdto.setUserid(user.getId());
                userRoleService.save(urdto);
            }
        }
        return new JsonResult(HttpStatus.OK, "添加成功 ", returnuserid);
    }


    @UncheckToken
    @ApiOperation(value = "登录")
    @RequestMapping(value = "/login", method = {RequestMethod.POST})
    public JsonResult login(String UserName, String PassWord) {
        if (StringUtil.isEmpty(UserName) || StringUtil.isEmpty(PassWord)) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "用户名或密码不能为空 ", null);
        }
        LoginResults result = userService.CheckUserNameAndPassword(UserName, PassWord);
        if (result == LoginResults.Success) {
            var userdto = userService.getOne(new QueryWrapper<TUsers>().eq("username", UserName));
            List<String> roles = new ArrayList<String>();
            userRoleService.list(new QueryWrapper<TUserroles>().select("RoleId").
                    eq("userId", userdto.getId())).forEach((item) -> {
                roles.add(item.getRoleid());
            });
            String[] permissions = permissionsService.getPermissionTargetByUserId(userdto.getId());
            LoginUserModel loginUserModel = new LoginUserModel(
                    userdto.getId(), userdto.getUsername(), userdto.getRealname(), StringUtils.join(permissions, ";"), "", StringUtils.join(roles, ";")
            );
            //生成jwt Token
            var jwtTokenResult = jwtHelper.generateToken(loginUserModel);
            String refresh_token = UUID.randomUUID().toString();
            jwtTokenResult.setRefresh_token(refresh_token);
            //将refreshToken存入redis 设置15天过期
            redisHelper.writeString(refresh_token, JsonUtil.Object2String(loginUserModel), 60 * 60 * 24 * 15);
            return new JsonResult(HttpStatus.OK, "登录成功", jwtTokenResult);
        } else if (result == LoginResults.NotExist) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "用户名不存在", null);
        } else {
            return new JsonResult(HttpStatus.BAD_REQUEST, "密码不正确", null);
        }
    }

    @UncheckToken
    @ApiOperation(value = "退出登录")
    @RequestMapping(value = "/loginOut", method = {RequestMethod.GET})
    public JsonResult loginOut(String refresh_token) {
        if (StringUtil.isEmpty(refresh_token)) {
            return new JsonResult(HttpStatus.OK, "成功", null);
        }
        redisHelper.delete(refresh_token);
        return new JsonResult(HttpStatus.OK, "成功", null);
    }

    @UncheckToken
    @ApiOperation(value = "刷新token")
    @RequestMapping(value = "/refreshToken", method = {RequestMethod.GET})
    public JsonResult refreshToken(String refreshToken) {
        if (StringUtil.isEmpty(refreshToken))
            return new JsonResult(HttpStatus.BAD_REQUEST, "refreshToken不能为空", null);
        var claims = redisHelper.readValue(refreshToken, LoginUserModel.class);
        LoginUserModel loginUserModel = new LoginUserModel();
        loginUserModel = (LoginUserModel) dataTransfer.getObjectFromObject(loginUserModel, claims);
        if (loginUserModel == null)
            return new JsonResult(HttpStatus.FORBIDDEN, "登录已过期", null);
        var jwtTokenResult = jwtHelper.generateToken(loginUserModel);
        jwtTokenResult.setRefresh_token(refreshToken);
        return new JsonResult(HttpStatus.OK, "成功", jwtTokenResult);
    }

    @ApiOperation(value = "删除用户")
    @RequestMapping(value = "/delete", method = {RequestMethod.POST})
    public JsonResult delete(String userId) {
        LOGGER.info("删除用户");
        var user = userService.getById(userId);
        if (user == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该用户不存在", null);
        } else {
            user.setIsdeleted(true);
            user.setDeleteruserid(currentUserId());
            userService.updateById(user);
            return new JsonResult(HttpStatus.OK, "删除成功", null);
        }

    }

    @ApiOperation(value = "获取用户列表")
    @RequestMapping(value = "/getList", method = {RequestMethod.GET})
    public JsonResult getList(String userName, Integer pageIndex, Integer pageSize) {
        Page<TUsers> page = new Page<>(pageIndex, pageSize);
        var queryWrapper = new QueryWrapper<TUsers>().eq("isdeleted", 0).like(!StringUtil.isEmpty(userName), "userName", userName).
                orderByDesc("creationtime");
        var list = userService.page(page, queryWrapper);
        return new JsonResult(HttpStatus.OK, "成功", list);
    }

    @ApiOperation(value = "获取用户角色")
    @RequestMapping(value = "/getUserRoles", method = {RequestMethod.GET})
    public JsonResult getUserRoles(String userId) {
        List<String> roles = new ArrayList<String>();
        userRoleService.list(new QueryWrapper<TUserroles>().select("RoleId").
                eq("UserId", userId)).forEach((item) -> {
            roles.add(item.getRoleid());
        });
        return new JsonResult(HttpStatus.OK, "成功", roles);
    }


    @ApiOperation(value = "获取用户")
    @RequestMapping(value = "/getInfo", method = {RequestMethod.GET})
    public JsonResult getInfo(String userId) {
        LOGGER.info("获取用户");
        var user = userService.getById(userId);
        if (user != null) {
            return new JsonResult(HttpStatus.OK, "成功", user);
        } else {
            return new JsonResult(HttpStatus.NOT_FOUND, "该用户不存在", null);
        }
    }


    @ApiOperation(value = "更新用户信息")
    @RequestMapping(value = "/update", method = {RequestMethod.POST})
    public JsonResult update(@RequestBody @ApiParam(name = "用户对象", value = "传入json格式", required = true) UserModel usermodel) {
        if (StringUtil.isEmpty(usermodel.getUserid())) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该用户Id不能为空", null);
        }
        var userd = userService.getById(usermodel.getUserid());
        if (userd == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该用户不存在", null);
        } else {
            userd.setRealname(usermodel.getRealname());
            userd.setStreetid(usermodel.getStreetid());
            userd.setNeighborhoodcommitteeid(usermodel.getNeighborhoodcommitteeid());
            userd.setRegionid(usermodel.getRegionid());
            if (usermodel.getRoles() != null && usermodel.getRoles().length > 0) {
                //先删除旧的角色
                userRoleService.remove(new QueryWrapper<TUserroles>().
                        eq("UserId", usermodel.getUserid()));
                //再批量新增新的角色
                List<TUserroles> roles = new ArrayList<>();
                for (String item : usermodel.getRoles()) {
                    TUserroles role = new TUserroles();
                    role.setUserid(usermodel.getUserid());
                    role.setRoleid(item);
                    roles.add(role);
                }
                userRoleService.saveBatch(roles);
            }
            boolean b = userService.updateById(userd);
            return new JsonResult(HttpStatus.OK, "更新成功", null);
        }
    }


    @ApiOperation(value = "修改密码")
    @RequestMapping(value = "/updatePassword", method = {RequestMethod.POST})
    public JsonResult updatePassword(String userid, String password, String confirmpassword) {
        LOGGER.info("修改密码");

        if (StringUtil.isEmpty(userid)) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "该用户Id不能为空", null);
        }
        if (StringUtil.isEmpty(password)) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "密码不能为空", null);
        }
        if (password.length() < 6) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "密码不能少于6位", null);
        }
        if (!password.equals(confirmpassword)) {
            return new JsonResult(HttpStatus.BAD_REQUEST, "密码与确认密码不一致", null);
        }
        var userdto = userService.getById(userid);
        if (userdto == null) {
            return new JsonResult(HttpStatus.NOT_FOUND, "该用户不存在", null);
        } else {
            userdto.setPassword(Utils.md5Encoding(Utils.md5Encoding(password) + userdto.getSalt()));
            userService.updateById(userdto);
            return new JsonResult(HttpStatus.OK, "更新成功", null);
        }
    }
}


